package xyj.sparrow.scheduler.server.connect;

import lombok.extern.slf4j.Slf4j;
import xyj.sparrow.common.connect.SparrowConnect;
import xyj.sparrow.scheduler.entity.App;
import xyj.sparrow.scheduler.mapper.AppMapper;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 本地连接管理
 *
 * @author 江南小俊
 * @since 2021/6/24
 **/
@Slf4j
public class LocalConnectManager implements ConnectManager {
    private final ConcurrentHashMap<String, CopyOnWriteArrayList<SparrowConnect>> connectMap =
            new ConcurrentHashMap<>();
    @Resource
    private AppMapper appMapper;

    @Override
    public void addConnect(SparrowConnect connect) {
        if (!connectMap.containsKey(connect.getAppId())) {
            synchronized (LocalConnectManager.class) {
                if (!connectMap.containsKey(connect.getAppId())) {
                    CopyOnWriteArrayList<SparrowConnect> sparrowConnects = new CopyOnWriteArrayList<>();
                    connectMap.put(connect.getAppId(), sparrowConnects);
                }
            }
        }
        connectMap.get(connect.getAppId()).add(connect);
    }

    @Override
    public void removeConnect(SparrowConnect connect) {
        connectMap.forEachValue(connectMap.size(), (value) -> {
            boolean remove = value.removeIf(item ->
                    item.getChannel().equals(connect.getChannel()));
            if (remove) {
                log.info("remove client success");
            }
        });
    }

    @Override
    public List<String> listConnectDesc(String appId) {
        if (connectMap.containsKey(appId)) {
            return connectMap.get(appId).stream().map(SparrowConnect::getConnectDesc).collect(Collectors.toList());
        } else {
            return new ArrayList<>();
        }

    }

    @Override
    public List<SparrowConnect> getConnect(String appId) {
        CopyOnWriteArrayList<SparrowConnect> sparrowConnects = connectMap.get(appId);
        if (sparrowConnects != null && !sparrowConnects.isEmpty()) {
            App app = appMapper.selectById(appId);
            switch (app.getStrategy()) {
                case -1: {
                    log.info("{}:最后一个客户端", app.getAppId());
                    //最后一个
                    SparrowConnect sparrowConnect = sparrowConnects.get(sparrowConnects.size() - 1);
                    sparrowConnect.setConnectIndex(sparrowConnects.size());
                    sparrowConnect.setConnectTotal(sparrowConnects.size());
                    return Collections.singletonList(sparrowConnect);
                }
                case 0: {
                    log.info("{}:广播全部", app.getAppId());
                    for (int i = 0; i < sparrowConnects.size(); i++) {
                        sparrowConnects.get(i).setConnectIndex(i + 1);
                        sparrowConnects.get(i).setConnectTotal(sparrowConnects.size());
                    }
                    //广播全部
                    return sparrowConnects;
                }
                case 1: {
                    log.info("{}:第一个客户端", app.getAppId());
                    //第一个
                    SparrowConnect sparrowConnect = sparrowConnects.get(0);
                    sparrowConnect.setConnectIndex(1);
                    sparrowConnect.setConnectTotal(sparrowConnects.size());
                    return Collections.singletonList(sparrowConnects.get(0));
                }
            }
        }
        return new ArrayList<>();
    }
}
